/*
*
==============================================================================
*  Name        : 
*  Part of     : Omen Game Engine
*  Description : 
*  Version     : 1.0
*
*  Copyright (c) 2013 Lauri Kortevaara.
* 
==============================================================================
*/

#pragma once

#include "OmenConfig.h"
#include "OmenDataTypes.h"

namespace Omen
{
    class OMEN_API Vector4d
    {
    public:
        Vector4d();
        Vector4d( const Omen::Float& x, const Omen::Float& y, const Omen::Float& z, const Omen::Float& w );    /// <summary>Constructs a 4d vector by given x,y,z,w compnents</summary>
        Vector4d( const Vector4d& other );                                            /// <summary>Constructs a 4d vector by copying another vector4d</summary>
        virtual ~Vector4d();

        virtual Omen::Float length() const;                        /// <summary>Returns the length of this vector</summary>
        virtual Omen::Float squaredLength() const;                 /// <summary>Returns the squared length of this vector</summary>

        void        normalize();                                /// <summary>Normalizes this vetor</summary>
        Vector4d    normalized() const;                            /// <summary>Returns a normalized form of this vector</summary>

        virtual void setCoordinates( const Omen::Float& x, const Omen::Float& y, const Omen::Float& z, const Omen::Float& _w  ); /// <summary>Sets the vector's components</summary>

        virtual Vector4d& operator =( const Omen::Vector4d& other );

        virtual float* operator&();                                 /// Get a float pointer to the vector
        virtual Vector4d& operator*=( Omen::Float scalar );      /// <summary>Multiplies the components of this Vector4d by given scalar and returns a reference to this vector</summary>
        virtual Vector4d& operator*=( const Vector4d& other );    /// <summary>Multiplies the components of this vector by corresponding components of given vector and returns a reference to this vector (e.g. dot product)</summary>
        virtual Vector4d& operator+=( const Vector4d& other );   /// <summary>Adds given Vector4d from this vector and returns a reference to this vector<summary>
        virtual Vector4d& operator-=( const Vector4d& other );   /// <summary>Subtracts given Vector4d from this vector and returns a reference to this vector<summary>
        virtual Vector4d& operator/=( Omen::Float scalar );      /// <summary>Divivdes the components of this Vector4d by given scalar and returns a reference to this vector</summary>

        virtual Vector4d operator*( Omen::Float scalar ) const;      /// <summary>Multiplies the components of this Vector4d by given scalar and returns a reference to this vector</summary>
        virtual Vector4d operator*( const Vector4d& other )const;    /// <summary>Multiplies the components of this vector by corresponding components of given vector and returns a reference to this vector (e.g. dot product)</summary>
        virtual Vector4d operator+( const Vector4d& other )const;   /// <summary>Adds given Vector4d from this vector and returns a reference to this vector<summary>
        virtual Vector4d operator-( const Vector4d& other )const;   /// <summary>Subtracts given Vector4d from this vector and returns a reference to this vector<summary>
        virtual Vector4d operator/( Omen::Float scalar )const;      /// <summary>Divivdes the components of this Vector4d by given scalar and returns a reference to this vector</summary>

        Omen::Float& operator[]( unsigned char col );
        const Omen::Float& operator[]( unsigned char col ) const;
    
    public:
        Omen::Float x,y,z,w;

    public: // Static member functions
        static Omen::Float  dotProduct ( const Vector4d& v1, const Vector4d& v2 );                    /// <summmry>Returns dot product of given two vectors</summary>
        static Vector4d     normal ( const Vector4d& v1, const Vector4d& v2 );                        /// <summary>Retruns a vector that is perpendicular to two given vectors</summary>
        static Vector4d     normal ( const Vector4d& v1, const Vector4d& v2, const Vector4d& v3 );  /// <summary>Returns a vector that is perpendicular to all of three given vectros</summary>

    };   

    /// Non Member Vector4d functions
    /*OMEN_API Omen::Vector4d operator*( Omen::Float scalar, const Omen::Vector4d & vector );
    OMEN_API Omen::Vector4d operator*( const Omen::Vector4d & vector, Omen::Float scalar );
    OMEN_API Omen::Vector4d operator*( const Omen::Vector4d & v1, const Omen::Vector4d & v2 );
    OMEN_API Omen::Vector4d operator+( const Omen::Vector4d & v1, const Omen::Vector4d & v2 );
    OMEN_API Omen::Vector4d operator-( const Omen::Vector4d& vector );
    OMEN_API Omen::Vector4d operator/ ( const Omen::Vector4d& vector, Omen::Float scalar );
    
    OMEN_API bool operator!= ( const Omen::Vector4d & v1, const Omen::Vector4d & v2 );
    OMEN_API bool operator== ( const Omen::Vector4d & v1, const Omen::Vector4d & v2 );*/
};

